package cn.minimelon.api.service.module.thread;

import cn.minimelon.api.domain.enums.SwTypeEnum;
import cn.minimelon.api.domain.common.ProgressInfo;
import cn.minimelon.api.domain.module.dto.ModelTaskData;
import cn.minimelon.api.domain.module.vo.DataModelVO;
import cn.minimelon.api.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Solon;
import org.noear.solon.data.annotation.TranAnno;
import org.noear.solon.data.cache.CacheService;
import org.noear.solon.data.tran.TranUtils;

import java.util.List;
import java.util.function.Function;

@Slf4j
public class ModelTaskRunnable implements Runnable {
    private final ModelTaskData taskData;

    private final Function<ModelTaskData, String> executor;

    private final CacheService cacheService;

    /**
     * 模型提交线程
     *
     * @param taskData 处理需要数据
     */
    public ModelTaskRunnable(ModelTaskData taskData, Function<ModelTaskData, String> executor) {
        this.taskData = taskData;
        this.executor = executor;
        this.cacheService = Solon.context().getBean(CacheService.class);
    }

    @Override
    public void run() {
        List<DataModelVO> list = taskData.getModelList();
        String progressKey = taskData.cacheKey();
        ProgressInfo progressInfo = new ProgressInfo(progressKey, list.size());
        cacheService.store(progressKey, progressInfo, 3600);
        for (DataModelVO model : list) {
            try {
                ModelTaskData data = new ModelTaskData();
                data.setTaskType(taskData.getTaskType());
                data.setUser(taskData.getUser());
                data.setDataModel(model);
                TranUtils.execute(new TranAnno(), () -> executor.apply(data));
                // execSubmitOne(model, user); // 新启事务
                // 成功数+1
                progressInfo.setSuccessNum(progressInfo.getSuccessNum() + 1);
                cacheService.store(progressKey, progressInfo, 3600);
            } catch (ServiceException ex) {
                // 失败数+1
                progressInfo.setFailNum(progressInfo.getFailNum() + 1);
                cacheService.store(progressKey, progressInfo, 3600);
                log.error("提交出错：{}", model.getCode(), ex);
            } catch (Throwable ex) {
                log.error("提交出错：未知错误", ex);
                progressInfo.setFailNum(progressInfo.getTotalNum() - progressInfo.getSuccessNum());
                break;
            }
        }
        // 完成保留5秒
        progressInfo.setDone(SwTypeEnum.YES.code());
        cacheService.store(progressKey, progressInfo, 5);
    }
}
